package net.towee.client.gadgets;

import net.towee.client.i18n.ToweeConstants;
import net.towee.client.resources.ClientResource;
import net.towee.model.utils.Pair;

import com.allen_sauer.gwt.dnd.client.DragController;
import com.allen_sauer.gwt.dnd.client.DragEndEvent;
import com.allen_sauer.gwt.dnd.client.DragHandler;
import com.allen_sauer.gwt.dnd.client.DragStartEvent;
import com.allen_sauer.gwt.dnd.client.VetoDragException;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class GadgetView extends FlowPanel implements GadgetPresenter.Display,
		HasValueChangeHandlers<Pair<Integer, Integer>> {
	protected final ToweeConstants constants;
	protected final ClientResource resource;

	private final FlowPanel shell = new FlowPanel();
	private final FlowPanel container = new FlowPanel();
	private Label closeButton = new Label("Close");
	private Label header = new Label();
	private boolean dragInit = false;

	public GadgetView(ToweeConstants constants, ClientResource resource) {
		this.constants = constants;
		this.resource = resource;

		super.add( shell );
		shell.getElement().setAttribute("shell", "");
		shell.getElement().getStyle().setPadding(5, Unit.PX);
		
		setStyleName(resource.css().gadget());
		createHeader();
		createContent();
	}

	protected void setHeader(String name) {
		header.setText(name);
	}

	@Override
	public void onAttach() {
		super.onAttach();

		// Get drag controller
		if (dragInit == false) {
			DragController controller = (DragController) (getParent().getLayoutData());
			controller.makeDraggable(this, header);
			controller.addDragHandler(new DragHandler() {
				@Override
				public void onDragEnd(DragEndEvent event) {
					int row = ((FlowPanel)getParent()).getWidgetIndex( GadgetView.this );
					int column = ((AbsolutePanel)getParent().getParent()).getWidgetIndex(getParent());
					
					// Fire change position event
					ValueChangeEvent.fire(GadgetView.this, new Pair<Integer, Integer>(row, column));
				}

				@Override
				public void onDragStart(DragStartEvent event) {
				}

				@Override
				public void onPreviewDragEnd(DragEndEvent event) throws VetoDragException {	
				}

				@Override
				public void onPreviewDragStart(DragStartEvent event) throws VetoDragException {					
				}
			});
			dragInit = true;
		}
	}

	private void createContent() {
		container.getElement().setAttribute("container", "");
		shell.add(container);
	}

	private void createHeader() {
		closeButton.getElement().setAttribute("button", "close");
		header.getElement().setAttribute("header", "");
		shell.add(closeButton);
		shell.add(header);

		closeButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				removeFromParent();
			}
		});
	}

	@Override
	public void add(Widget w) {
		container.add(w);
	}

	@Override
	public HasClickHandlers getCloseButton() {
		return closeButton;
	}

	@Override
	public HasClickHandlers getMinimizeButton() {
		return new Button();
	}

	@Override
	public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Pair<Integer, Integer>> handler) {
		return addHandler(handler, ValueChangeEvent.getType());
	}

	@Override
	public HasValueChangeHandlers<Pair<Integer, Integer>> getPositionChanger() {
		return this;
	}

}
